5.5
1. yield
参考链接: https://www.jianshu.com/p/103cbf359971
当函数需要返回一个迭代器的时候, 逐个返回值;生成器yield关键字不是返回值,他的专业术语叫产出值,只是生成一个值
未使用yield, 内存使用输出如下
1.15 MB
9.15 MB
17.15 MB
33.15 MB
function getValues() {
$valuesArray = [];
// 获取初始内存使用量
echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL;
for ($i = 1; $i < 800000; $i++) {
$valuesArray[] = $i;
// 为了让我们能进行分析,所以我们测量一下内存使用量
if (($i % 200000) == 0) {
// 来 MB 为单位获取内存使用量
echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. PHP_EOL;
}
}
return $valuesArray;
}
$myValues = getValues(); // 一旦我们调用函数将会在这里创建数组
foreach ($myValues as $value) {}
使用yield, 内存使用输出如下
1.15 MB
1.15 MB
1.15 MB
1.15 MB
function getValues()
{
// 获取内存使用数据
echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL;
for ($i = 1; $i < 800000; $i++) {
yield $i;
// 做性能分析,因此可测量内存使用率
if (($i % 200000) == 0) {
// 内存使用以 MB 为单位
echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL;
}
}
}
$myValues = getValues(); // 在循环之前都不会有动作
foreach ($myValues as $value) {} // 开始生成数据
执行过程
- 首先调用 createRange 函数,传入参数5,但是 for 值执行了一次然后停止了,并且告诉 foreach 第一次循环可以用的值。
- foreach 开始对 $result 循环,进来首先 sleep(1) ,然后开始使用 for 给的一个值执行输出。
- foreach 准备第二次循环,开始第二次循环之前,它向 for 循环又请求了一次。
- for 循环于是又执行了一次,将生成的时间戳告诉 foreach
- foreach 拿到第二个值,并且输出。由于 foreach 中 sleep(1) ,所以, for 循环延迟了1秒生成当前时间
function createRange($number)
{
for ($i = 0; $i < $number; $i++) {
yield time();
}
}
$result = createRange(3); // 这里调用上面我们创建的函数
foreach ($result as $value) {
sleep(1);
echo $value, PHP_EOL;
}
/*
1564559537
1564559538
1564559539
*/
读取5G大文件实例
header('content-type:text/html;charset=utf-8');
function readTxt()
{
$handle = fopen('../txt/t2.txt', 'rb');
while (feof($handle) === false) {
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
echo $value . PHP_EOL;
}
2. list()
用于foreach 可以用 list() 在 foreach 中解析嵌套的数组
$array = [
[1, 2, 3],
[4, 5, 6],
];
foreach ($array as list($a, $b, $c))
echo "{$a} {$b} {$c}\n";
/*
1 2 3
4 5 6
*/
3. array和string变量可以直接取值
echo [1, 2, 3][0], PHP_EOL; // 1
echo 'PHP'[0], PHP_EOL; // p
4. empty()支持任意表达式
function always_false()
{
return false;
}
if (empty(always_false())) echo '1';
if (empty(true)) echo '2';
if (empty(1 + 1)) echo '3';
if (empty(1 > 0)) echo '4';
// This will be printed.
5. try-catch结构新增finally块
try {
throw new Exception('1');
} catch (Exception $e) {
echo $e->getMessage(), PHP_EOL; // 1
} finally { // 只要执行了try或者catch, 就一定会执行finally
echo '2', PHP_EOL; // 2
}
6. 可用MyClass::class取到类的完整限定名(包括命名空间);
namespace app\api;
class A
{
public function get()
{
echo self::class; // app\api\A
}
}
echo A::class; // app\api\A
细节修改
不推荐使用 mysql 函数,推荐使用 PDO 或 MySQLi;